using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Cryptography;
using System.Text;
using Admin2025.Application.Dtos;
using Admin2025.Application.DTOs;
using Admin2025.Application.IServices;
using Admin2025.Domain.Entities.App;
using Admin2025.Domain.Repositories;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;

namespace Admin2025.Application.Services;

// 负责处理登录逻辑：查找用户、验证密码
public class AuthService : IAuthService
{
  private readonly IUserRepository _userRepository;
  private readonly IConfiguration _config;

  public AuthService(IUserRepository userRepository, IConfiguration config)
  {
    _userRepository = userRepository;
    _config = config;
  }

  public async Task<(string Token, UserDto User)?> LoginAsync(LoginDto loginDto)
  {
    var user = await _userRepository.GetByUsernameAsync(loginDto.Username);
    if (user == null || !VerifyPassword(loginDto.Password, user.PasswordHash))
      return null;

    // return GenerateJwtToken(user);
    var token = GenerateJwtToken(user);
    var userDto = new UserDto
    {
      UserId = user.Id,
      Username = user.UserName,
      Email = user.Email
    };
    return (token, userDto);
  }
  public async Task<(string Token, UserDto User)?> RegisterAsync(RegisterDto registerDto)
  {
    var existingUser = await _userRepository.GetByUsernameAsync(registerDto.Username);
    if (existingUser != null)
    {
      return null;
    }

    var user = new AppUser
    {
      Id = Guid.NewGuid(),
      UserName = registerDto.Username,
      Email = registerDto.Email,
      Salt = BCrypt.Net.BCrypt.GenerateSalt(),
      PasswordHash = BCrypt.Net.BCrypt.HashPassword(registerDto.Password)
    };

    await _userRepository.CreateUserAsync(user);

    var token = GenerateJwtToken(user);
    var userDto = new UserDto
    {
      UserId = user.Id,
      Username = user.UserName,
      Email = user.Email
    };
    return (token, userDto);
  }

  private string GenerateJwtToken(AppUser user)
  {
    var claims = new[]
    {
        new Claim(ClaimTypes.NameIdentifier, user.Id.ToString()),
        new Claim(ClaimTypes.Name, user.UserName),
        new Claim(ClaimTypes.Email, user.Email),
        new Claim(ClaimTypes.Role, "SuperAdmin")
    };

    var jwtKey = _config["Jwt:Key"];
    if (string.IsNullOrEmpty(jwtKey))
    {
      throw new InvalidOperationException("JWT key is not configured.");
    }

    var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtKey));
    var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

    var expireMinutes = _config["Jwt:ExpireMinutes"];
    if (string.IsNullOrEmpty(expireMinutes) || !int.TryParse(expireMinutes, out int minutes))
    {
      minutes = 120; // 默认值为 120 分钟
    }

    var token = new JwtSecurityToken(
        issuer: _config["Jwt:Issuer"],
        audience: _config["Jwt:Audience"],
        claims: claims,
        expires: DateTime.UtcNow.AddMinutes(minutes),
        signingCredentials: creds);

    return new JwtSecurityTokenHandler().WriteToken(token);
  }

  private string HashPassword(string password)
  {
    // 使用 BCrypt 生成密码哈希
    return BCrypt.Net.BCrypt.HashPassword(password);
  }

  private bool VerifyPassword(string password, string storedHash)
  {
    // 使用 BCrypt 验证密码
    return BCrypt.Net.BCrypt.Verify(password, storedHash);
    // return HashPassword(password) == storedHash;
  }
}